package com.sun.dream.fish.util;

/**
 * Description:
 * Created By ljl on 2023/12/21.
 */

import com.sun.dream.fish.frontmodel.named.I18nEnum;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class PackageScanner {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String packageName = "com.sun"; // 指定包名
        Class<?> interfaceClass = I18nEnum.class; // 指定接口类

        List<Class<?>> implementationClasses = getSubTypesOf(packageName, interfaceClass);
        for (Class<?> clazz : implementationClasses) {
            System.out.println(clazz.getName());
        }
    }

    public static List<Class<?>> getSubTypesOf(String packageName, Class<?> interfaceClass) throws IOException, ClassNotFoundException {
        List<Class<?>> implementationClasses = new ArrayList<>();
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        String path = packageName.replace('.', '/');
        Enumeration<URL> resources = classLoader.getResources(path);
        while (resources.hasMoreElements()) {
            URL resource = resources.nextElement();
            File file = new File(resource.getFile());
            scanDirectory(file, packageName, implementationClasses, interfaceClass);
        }
        return implementationClasses;
    }

    public static void scanDirectory(File directory, String packageName, List<Class<?>> implementationClasses, Class<?> interfaceClass) throws ClassNotFoundException {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    String subPackageName = packageName + "." + file.getName();
                    scanDirectory(file, subPackageName, implementationClasses, interfaceClass);
                } else if (file.getName().endsWith(".class")) {
                    String className = packageName + "." + file.getName().substring(0, file.getName().length() - 6);
                    Class<?> clazz = Class.forName(className);
                    if (clazz.isEnum() && interfaceClass.isAssignableFrom(clazz)) {
                        implementationClasses.add(clazz);
                    }
                }
            }
        }
    }
}
